package com.elitedatai.mchtest.component.websocket.service.impl;

import com.dji.sdk.websocket.WebSocketMessageResponse;
import com.elitedatai.mchtest.component.websocket.config.MyConcurrentWebSocketSession;
import com.elitedatai.mchtest.component.websocket.service.IWebSocketManageService;
import com.elitedatai.mchtest.component.websocket.service.IWebSocketMessageService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.TextMessage;

import java.io.IOException;
import java.util.Collection;
import java.util.Objects;

@Service
@Slf4j
public class WebSocketMessageServiceImpl implements IWebSocketMessageService {

    @Autowired
    private ObjectMapper mapper;

    @Autowired
    private IWebSocketManageService webSocketManageService;

    @Override
    public void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message) {
        // 检查会话是否为空，为空则直接返回
        if (session == null) {
            return;
        }

        try {
            // 检查会话是否已打开，如果未打开则关闭会话并记录日志
            if (!session.isOpen()) {
                session.close();
                log.debug("This session is closed.");
                return;
            }

            // 将消息对象序列化为JSON字节数组并发送文本消息
            session.sendMessage(new TextMessage(mapper.writeValueAsBytes(message)));
        } catch (IOException e) {
            // 处理消息发送失败的情况，记录错误日志
            log.info("Failed to publish the message. {}", message.toString());
            e.printStackTrace();
        }
    }

    @Override
    public void sendBatch(Collection<MyConcurrentWebSocketSession> sessions, WebSocketMessageResponse message) {
        // 检查会话集合是否为空，为空则直接返回
        if (sessions.isEmpty()) {
            return;
        }

        try {
            // 将消息对象序列化为JSON字节数组创建文本消息
            TextMessage data = new TextMessage(mapper.writeValueAsBytes(message));

            // 遍历所有会话并发送消息
            for (MyConcurrentWebSocketSession session : sessions) {
                // 检查会话是否已打开，如果未打开则关闭会话并记录日志
                if (!session.isOpen()) {
                    session.close();
                    log.debug("This session is closed.");
                    return;
                }
                // 向当前会话发送消息
                session.sendMessage(data);
            }

        } catch (IOException e) {
            // 处理批量消息发送失败的情况，记录错误日志
            log.info("Failed to publish the message. {}", message.toString());

            e.printStackTrace();
        }
    }

    @Override
    public void sendBatch(String workspaceId, Integer userType, String bizCode, Object data) {
        // 检查工作空间ID是否为空或空白，如果是则抛出异常
        if (!StringUtils.hasText(workspaceId)) {
            throw new RuntimeException("Workspace ID 不存在");
        }

        // 根据用户类型参数获取对应的工作空间会话集合
        // 如果userType为null，获取工作空间的所有会话
        // 如果userType不为null，获取工作空间中指定用户类型的会话
        Collection<MyConcurrentWebSocketSession> sessions = Objects.isNull(userType) ?
                webSocketManageService.getValueWithWorkspace(workspaceId) :
                webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType);

        // 调用批量发送方法，构建WebSocket消息响应对象
        this.sendBatch(sessions, new WebSocketMessageResponse()
                .setData(Objects.requireNonNullElse(data, ""))  // 设置消息数据，如果data为null则使用空字符串
                .setTimestamp(System.currentTimeMillis())       // 设置当前时间戳
                .setBizCode(bizCode));                           // 设置业务代码
    }

    @Override
    public void sendBatch(String workspaceId, String bizCode, Object data) {
        // 重载方法：发送批量消息到指定工作空间的所有用户
        // 调用上面的sendBatch方法，userType参数设为null表示不限制用户类型
        this.sendBatch(workspaceId, null, bizCode, data);
    }
}